/* Copyright (c) 2024 Huawei Technologies Co., Ltd.
openFuyao is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
         http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN 'AS IS' BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details. */
import BreadCrumbCom from '../components/BreadCrumbCom';
import ColocationTableModal from '../components/ColocationTableModal';
import ColocationDeleteModal from '../components/ColocationDeleteModal';
import { containerRouterPrefix, ResponseCode } from '../common/constants';
import { useParams } from 'inula-router';
import { useEffect, useState, useCallback } from 'openinula';
import { SyncOutlined, MinusCircleOutlined, CloseOutlined } from '@ant-design/icons';
import { Form, Table, ConfigProvider, Space, Input, Button, message, Switch } from 'antd';
import zhCN from 'antd/es/locale/zh_CN';
import { getNodeListData, getNodesAndPodsCount, deleteColocationNodesById, addColocationNodes, getNonColocationNodeListData, setOneNodeOversold } from '../api/colocationApi';
import '../styles/colocationNodeManagementPage.less';
import { sorterFirstAlphabe } from '../tools/utils';
import useLocalStorage from '@/hooks/useLocalStorage';
import ToolTipComponent from '@/components/ToolTipComponent';
import { filterStatusName } from '../utils/common';

export default function ColocationNodeManagementPage() {
  const [currentTheme, setCurrentTheme] = useLocalStorage('theme', 'light');
  const [isShow, setIsShow] = useState(true);
  const param = useParams();
  const [colocationNodeForm] = Form.useForm();
  const [selectedRowKeys, setSelectedRowKeys] = useState([]);
  const [selectedRows, setSelectedRows] = useState([]);
  const [messageApi, contextHolder] = message.useMessage();
  // table部分
  const [originalList, setOriginalList] = useState([]); // 原始数据
  const [colocationNodeLoading, setColocationNodeLoading] = useState(false);
  const [colocationNodeList, setColocationNodeList] = useState([]); // 工作负载table数据集
  const [colocationNodePage, setColocationNodePage] = useState(1);
  const [filterNodeStatus, setFilterNodeStatus] = useState([{ text: '正常', value: '正常' }, { text: '异常', value: '异常' }]); // 筛选项
  const [filterNodeValue, setFilterNodeValue] = useState(); // 筛选值
  // 添加弹窗
  const [colocationTableModal, setColocationTableModal] = useState(false);
  const [modelColocationNodelist, setModelColocationNodelist] = useState([]);
  // 删除提醒弹窗
  const [deleteModal, setDeleteModal] = useState(false);
  const [deleteName, setDeleteName] = useState('');
  // 删除勾选
  const [isNodeDelCheck, setIsNodeDelCheck] = useState(false); // 是否选中
  // 变混部删除勾选
  const [isColocationNodeDelCheck, setIsColocationNodeDelCheck] = useState(false); // 是否选中
  // 列表项
  const workLoadColumns = [
    {
      title: '节点名称',
      key: 'node_name',
      dataIndex: 'name',
      width: 300,
      sorter: (a, b) => sorterFirstAlphabe(a.name, b.name),
      render: (_, record) => <Space>
        {record.name}
      </Space>,
    },
    {
      title: '状态',
      key: 'node_status',
      width: 200,
      filters: filterNodeStatus,
      filterMultiple: false,
      filteredValue: filterNodeValue ? [filterNodeValue] : [],
      onFilter: (value, record) => filterStatusName(record.nodeStatus) === value,
      sorter: (a, b) => sorterFirstAlphabe(a.osImage, b.osImage),
      render: (_, record) => <Space>
        <div className='table_single_box'>
          <div className='table_single_box_status_box'>
            <span className={`${record.nodeStatus.toLowerCase()}_circle`}></span>
            <span>{(record.nodeStatus === 'active' || record.nodeStatus === 'inactive') ? filterStatusName(record.nodeStatus) : '--'}</span>
          </div>
        </div>
      </Space>,
    },
    {
      title: 'IP地址',
      key: 'node_tune',
      width: 200,
      sorter: (a, b) => sorterFirstAlphabe(a.addresses, b.addresses),
      render: (_, record) => <>
        {record.addresses?.map(item => {
          return <div className='table_tuning_box'><p>{item}</p></div>;
        })}
      </>,
    },
    {
      title: 'OS',
      key: 'node_cup',
      width: 200,
      sorter: (a, b) => sorterFirstAlphabe(a.osImage, b.osImage),
      render: (_, record) => <Space>
        <div className='table_single_box'>
          <div className='table_single_box_number_format'>
            <span>{record.osImage}</span>
          </div>
        </div>
      </Space>,
    },
    {
      title: '设置为超卖',
      key: 'node_setting',
      width: 100,
      sorter: (a, b) => sorterFirstAlphabe(a.isOversold, b.isOversold),
      render: (_, record) => (
        <Switch
          checked={record.isOversold}
          key={record.id}
          onChange={() => handleSwitchChange(record.uid, record['oversubscription-status'])}
        />
      ),
    },
    {
      title: '设置为非混部节点',
      key: 'handle',
      width: 150,
      render: (_, record) => (
        <Space>
          <MinusCircleOutlined className='table_handle' onClick={() => { handleDeleteNode(record) }} />
        </Space>
      ),
    },
  ];

  // 弹窗列表项
  const modelColumns = [
    {
      title: '节点名称',
      key: 'node_name',
      dataIndex: 'name',
      sorter: (a, b) => sorterFirstAlphabe(a.name, b.name),
      render: (_, record) => <Space>
        {record.name}
      </Space>,
    },
    {
      title: 'IP地址',
      key: 'node_tune',
      sorter: (a, b) => sorterFirstAlphabe(a.addresses, b.addresses),
      render: (_, record) => <>
        {record.addresses?.map(item => {
          return <div className='table_tuning_box'><p>{item}</p></div>;
        })}
      </>,
    },
    {
      title: 'OS',
      key: 'node_cup',
      sorter: (a, b) => sorterFirstAlphabe(a.osImage, b.osImage),
      render: (_, record) => <Space>
        <div className='table_single_box'>
          <div className='table_single_box_number_format'>
            <span>{record.osImage}</span>
          </div>
        </div>
      </Space>,
    },
    {
      title: '设置为超卖',
      key: 'node_setting',
      render: (text, record) => <Space>
        <Switch
          checked={record.isOversold}
          key={record.id}
          disabled={record.name === 'fuyao-master'}
          onChange={() => handleSwitchChangeToNoColocationList(record.uid, record.isOversold)}
        />
      </Space>,
    },
  ];

  const handleShowChange = () => {
    setIsShow(false);
  };

  const handleSwitchChange = async (id, checked) => {
    const ary = JSON.parse(JSON.stringify(colocationNodeList));
    let dataObj = {};
    ary.forEach(item => {
      if (item.uid === id) {
        dataObj = item;
        if (item.isOversold === true) {
          item['oversubscription-status'] = 'false';
        } else {
          item['oversubscription-status'] = 'true';
        }
      }
    });
    // 此处直接调接口修改混部节点列表isOversold的状态后刷新页面
    try {
      const res = await setOneNodeOversold(dataObj.name, dataObj['oversubscription-status']);
      if (res.status === ResponseCode.OK) {
        messageApi.success('设置成功');
      } else {
        messageApi.error('设置失败');
      }
    } catch (e) {
      messageApi.error('接口异常');
    }
    setColocationNodeList(ary);
    getColocationNodeList();
  };

  // 设置非混部table的switch开关
  const handleSwitchChangeToNoColocationList = (id, checked) => {
    const ary = JSON.parse(JSON.stringify(modelColocationNodelist));
    ary.forEach(item => {
      if (item.uid === id) {
        item.isOversold = !item.isOversold;
      }
    });
    // 数组对比取交集改变选中行的开关状态
    const intersection = ary.filter(obj1 => selectedRows.some(obj2 => obj2.uid === obj1.uid));
    setModelColocationNodelist(ary);
    setSelectedRows(intersection);
  };

  // 获取colocationNodeList
  const getColocationNodeList = useCallback(async (isChange = true) => {
    setColocationNodeLoading(true);
    try {
      // 此处接口
      const res = await getNodeListData();
      if (res.status === ResponseCode.OK) {
        const arr = res.data?.data?.map((item, index) => {
          return {
            ...item,
            key: item.uid,
          };
        });
        const sorterArr = arr.sort((a, b) => b.nodeStatus.localeCompare(a.nodeStatus));
        setOriginalList(sorterArr);
        handleSearchColocationNode(sorterArr, isChange); // 先搜索
      } else {
        messageApi.error('接口异常');
      }
    } catch (e) {
      setColocationNodeList([]); // 数组为空
    }
    setColocationNodeLoading(false);
  }, []);

  // 获取非混部节点列表
  const getNonColocationNodeList = useCallback(async () => {
    try {
      // 此处接口
      const res = await getNonColocationNodeListData();
      if (res.status === ResponseCode.OK) {
        const arr = res.data.data.map((item, index) => {
          return {
            ...item,
            key: item.uid,
          };
        });
        const sorterArr = arr.sort((a, b) => b.nodeStatus.localeCompare(a.nodeStatus));
        setModelColocationNodelist(sorterArr);
      } else {
        messageApi.error('接口异常');
      }
    } catch (e) {
      setModelColocationNodelist([]); // model数组为空
    }
  }, []);

  // 外部检索
  const handleSearchColocationNode = (totalData = originalList, isChange = true) => {
    const colocationNodeFormName = colocationNodeForm.getFieldValue('colocationNode_name');
    let temporyList = totalData;
    if (colocationNodeFormName) {
      temporyList = temporyList.filter(item => (item.name).toLowerCase().includes(colocationNodeFormName.toLowerCase()));
    }
    setColocationNodeList([...temporyList]);
    isChange ? setColocationNodePage(1) : null;
  };

  const handleNodeTableChange = useCallback(
    (
      _pagination,
      filter,
      _sorter,
      extra
    ) => {
      if (extra.action === 'filter') {
        setFilterNodeValue(filter.node_status);
      }
    },
    []
  );

  // 混部节点移除
  const handleDeleteNode = async (record) => {
    setDeleteModal(true);
    setDeleteName(record.name);
  };

  const refreshModelData = () => {
    setSelectedRowKeys([]);
    setSelectedRows([]);
  };

  // 打开model
  const openButton = () => {
    setColocationTableModal(true);
    getNonColocationNodeList();
  };

  // 混部选择
  const rowSelection = {
    selectedRowKeys,
    onChange: (newSelectedRowKeys, newselectedRows) => {
      setSelectedRowKeys(newSelectedRowKeys);
      setSelectedRows(newselectedRows);
    },
    getCheckboxProps: (record) => ({
      name: record.name,
      disabled: record.nodeStatus === 'failed',
    }),
  };

  // 混部model的确定按钮
  const handleNodeConfirmBack = async (data) => {
    // 代接口
    try {
      const res = await addColocationNodes(data);
      if (res.status === ResponseCode.OK) {
        messageApi.success('添加成功');
      } else {
        messageApi.error('添加失败');
      }
    } catch (e) {
      messageApi.error('接口异常');
    }
    setColocationTableModal(false);
    setIsColocationNodeDelCheck(false);
    refreshModelData();
    getColocationNodeList();
  };

  // 混部model的取消按钮
  const handleNodeCancel = () => {
    setColocationTableModal(false);
    setIsColocationNodeDelCheck(false);
    refreshModelData();
  };

  // 设置非混部的确定按钮
  const handleDeleteConfirmBack = async () => {
    // 此处接口
    try {
      const res = await deleteColocationNodesById(deleteName);
      if (res.status === ResponseCode.OK) {
        messageApi.success('非混部设置成功');
        getColocationNodeList();
      } else {
        messageApi.error('非混部设置失败');
      }
    } catch (e) {
      messageApi.error('接口异常');
    }
    setDeleteModal(false);
    setIsNodeDelCheck(false);
  };

  // 设置非混部的取消按钮
  const handleDeleteCancel = () => {
    setDeleteModal(false);
    setIsNodeDelCheck(false);
    setColocationTableModal(false);
  };

  // 重置按钮
  const handleColocationNodeReset = () => {
    getColocationNodeList();
  };

  // 勾选回调
  const handleNodeCheckFn = (e) => {
    setIsNodeDelCheck(e.target.checked);
  };

  // 非混部列表勾选回调
  const handleColocationNodeCheckFn = (e) => {
    setIsColocationNodeDelCheck(e.target.checked);
  };

  useEffect(() => {
    getColocationNodeList();
  }, [getColocationNodeList]);

  return <div className="child_content">
    <BreadCrumbCom className="create_bread" items={[
      { title: '在离线混部', path: `/ColocationNodeManagement` },
      { title: '节点管理', path: `/` },
    ]} />
    {contextHolder}
    <div className='hybrid_detail_content'>
      <div className={`${isShow ? '' : 'cant_show'}`}>
        <ToolTipComponent>
          <div className="daemonsetDetail" style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
            <div className='promot-box'>混部节点仅可以部署在离线混部业务，超卖节点支持超卖节点资源，超卖节点只能是混部节点。</div>
            <CloseOutlined onClick={handleShowChange} />
          </div>
        </ToolTipComponent>
      </div>
      <div className='hybrid_detail_content_box'>
        <div className={` ${isShow ? 'tooltip_container_height' : 'normal_container_height'}`} >
          <div className='hybrid_detail_form'>
            <Form className="hybrid-searchForm form_padding_bottom" form={colocationNodeForm}>
              <Form.Item name="colocationNode_name" className="hybrid-search-input">
                <Input.Search placeholder="搜索节点名称" onSearch={() => handleSearchColocationNode()} autoComplete="off" maxLength={53} />
              </Form.Item>
              <Form.Item>
                <Space>
                  <Button className='hybrid_detail_form_button' onClick={openButton}>
                    添加混部节点
                  </Button>
                  <Button icon={<SyncOutlined />} onClick={handleColocationNodeReset} className="reset_btn" style={{ marginLeft: '16px' }}></Button>
                </Space>
              </Form.Item>
            </Form>
          </div>
          <div className='hybrid_detail_content_table'>
            <ConfigProvider locale={zhCN}>
              <Table
                loading={colocationNodeLoading}
                columns={workLoadColumns}
                dataSource={colocationNodeList}
                onChange={handleNodeTableChange}
                pagination={{
                  className: 'colocation-website-page',
                  current: colocationNodePage,
                  showTotal: (total) => `共${total}条`,
                  showSizeChanger: true,
                  showQuickJumper: true,
                  pageSizeOptions: [10, 20, 50],
                  onChange: (page) => setColocationNodePage(page),
                }}
              >
              </Table>
            </ConfigProvider>
          </div>
        </div>
      </div>

      <ColocationTableModal
        title="添加混部节点"
        open={colocationTableModal}
        cancelFn={handleNodeCancel}
        tableColumns={modelColumns}
        dataSource={modelColocationNodelist}
        rowSelection={rowSelection}
        confirmFn={handleNodeConfirmBack}
        selectedRows={selectedRows}
        refresh={refreshModelData}
        isCheck={isColocationNodeDelCheck}
        checkFn={handleColocationNodeCheckFn}
      />

      <ColocationDeleteModal
        title="设置为非混部节点"
        open={deleteModal}
        cancelFn={handleDeleteCancel}
        content={[
          `确定将混部节点 ${deleteName} 设置为非混部节点吗？`,
        ]}
        confirmFn={handleDeleteConfirmBack}
        isCheck={isNodeDelCheck}
        showCheck={true}
        checkFn={handleNodeCheckFn}
      />
    </div>
  </div>;
}